package com.bcinfo.iccard.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.bcinfo.iccard.constant.DownloadConstant;

public class DownloadUtils
{
    /**
     * 单个文件下载 <br/>
     * <p>
     * Description: TODO(详细描述) <br/>
     * <p>
     * Author: Administrator<br/>
     * <p>
     * Date: 2013-12-25-下午01:56:21<br/>
     * <p>
     * 
     * @param path
     * @param request
     * @param response
     * @return
     * @throws Exception
     * 
     */
    public static HttpServletResponse downLoadFile(String path, HttpServletRequest request, HttpServletResponse response)
            throws Exception
    {
        File file = new File(path);
        if (!file.exists())
        {
            System.out.println("文件不存在");
            return response;
        }
        // 取得文件名。
        String filename = file.getName();
        // 取得文件的后缀名。
        String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();
        OutputStream os = null;
        // 以流的形式下载文件。
        FileInputStream fis = null;
        try
        {
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
            response.setCharacterEncoding("utf-8");
            response.setContentType(CodeUtil.ext2ct(ext));
            fis = new FileInputStream(path);
        }
        catch (FileNotFoundException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try
        {
            BufferedInputStream buff = new BufferedInputStream(fis);
            byte[] b = new byte[1024];// 相当于我们的缓存
            long k = 0;// 该值用于计算当前实际下载了多少字节
            // 从response对象中得到输出流,准备下载
            os = response.getOutputStream();
            // 开始循环下载
            while (k < file.length())
            {
                int j = buff.read(b, 0, 1024);
                k += j;
                // 将b中的数据写到客户端的内存
                os.write(b, 0, j);
            }
            // 将写入到客户端的内存的数据,刷新到磁盘
            os.flush();

        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (os != null)
            {
                try
                {
                    os.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
        return response;
    }

    /**
     * 文件打包下载 <br/>
     * <p>
     * Description: TODO(详细描述) <br/>
     * <p>
     * Author: Administrator<br/>
     * <p>
     * Date: 2013-12-25-下午01:56:08<br/>
     * <p>
     * 
     * @param paths
     * @param tempPath
     * @param request
     * @param response
     * @return
     * @throws Exception
     * 
     */
    public static HttpServletResponse downLoadFiles(List<String> paths, String tempPath, HttpServletRequest request,
            HttpServletResponse response) throws Exception
    {
        try
        {
            /**
             * 创建一个临时压缩文件，
             * 我们会把文件流全部注入到这个文件中
             */
            File dirfile = new File(tempPath);
            if (!dirfile.exists())
            {
                dirfile.mkdirs();
            }
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
            Date date = new Date(System.currentTimeMillis());
            String sid = dateFormat.format(date);

            tempPath = tempPath + File.separator + sid + DownloadConstant.TEMP_ZIP_NAME;
            File file = new File(tempPath);
            if (!file.exists())
            {
                file.createNewFile();
            }
            response.reset();
            // response.getWriter()
            // 创建文件输出流
            FileOutputStream fous = new FileOutputStream(file);
            /**
             * 打包的方法我们会用到ZipOutputStream这样一个输出流,
             * 所以这里我们把输出流转换一下
             */
            ZipOutputStream zipOut = new ZipOutputStream(fous);
            /**
             * 这个方法接受的就是一个所要打包文件的集合，
             * 还有一个ZipOutputStream
             */
            zipFile(paths, zipOut);
            zipOut.close();
            fous.close();
            return downloadFile(file, response);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return response;
    }

    /**
     * 把接受的全部文件打成压缩包
     * <p>
     * Description: TODO(详细描述) <br/>
     * <p>
     * Author: Administrator<br/>
     * <p>
     * Date: 2013-12-25-下午01:55:31<br/>
     * <p>
     * 
     * @param paths
     * @param outputStream
     * 
     */
    public static void zipFile(List<?> paths, ZipOutputStream outputStream)
    {
        int size = paths.size();
        for (int i = 0; i < size; i++)
        {
            String path = (String) paths.get(i);
            // File file = (File) files.get(i);
            zipFile(path, outputStream);
        }
    }

    /**
     * 根据输入的文件与输出流对文件进行打包
     * <p>
     * Description: TODO(详细描述) <br/>
     * <p>
     * Author: Administrator<br/>
     * <p>
     * Date: 2013-12-25-下午01:55:19<br/>
     * <p>
     * 
     * @param path
     * @param ouputStream
     * 
     */
    public static void zipFile(String path, ZipOutputStream ouputStream)
    {
        File file = new File(path);
        if (!file.exists())
        {
            System.out.println("文件不存在");
        }
        try
        {
            if (file.exists())
            {
                /**
                 * 如果是目录的话这里是不采取操作的，
                 * 至于目录的打包正在研究中
                 */
                if (file.isFile())
                {
                    FileInputStream IN = new FileInputStream(file);
                    BufferedInputStream bins = new BufferedInputStream(IN, 512);
                    // org.apache.tools.zip.ZipEntry
                    ZipEntry entry = new ZipEntry(file.getName());
                    ouputStream.putNextEntry(entry);
                    // 向压缩文件中输出数据
                    int nNumber;
                    byte[] buffer = new byte[512];
                    while ((nNumber = bins.read(buffer)) != -1)
                    {
                        ouputStream.write(buffer, 0, nNumber);
                    }
                    // 关闭创建的流对象
                    bins.close();
                    IN.close();
                }
                else
                {
                    try
                    {
                        File[] files = file.listFiles();
                        for (int i = 0; i < files.length; i++)
                        {
                            File _file = files[i];
                            String _path = _file.getPath();
                            zipFile(_path, ouputStream);
                        }
                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                }
            }
            else
            {
                System.out.println("文件不存在");
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * 一句话描述 <br/>
     * <p>
     * Description: TODO(详细描述) <br/>
     * <p>
     * Author: Administrator<br/>
     * <p>
     * Date: 2013-12-25-下午01:57:09<br/>
     * <p>
     * 
     * @param file
     * @param response
     * @return
     * @throws IOException
     * 
     */
    public static HttpServletResponse downloadFile(File file, HttpServletResponse response) throws IOException
    {
        OutputStream toClient = null;
        try
        {
            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(file.getPath()));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();

            toClient = new BufferedOutputStream(response.getOutputStream());
            // response.setContentType("application/octet-stream");
            String filename = file.getName();
            // 取得文件的后缀名。
            String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();
            response.setContentType(CodeUtil.ext2ct(ext));
            response.setHeader("Content-Disposition", "attachment;filename=" + filename);
            toClient.write(buffer);
            toClient.flush();

        }
        catch (IOException ex)
        {
            ex.printStackTrace();
        }
        finally
        {
            toClient.close();
            try
            {
                // File f = new File(file.getPath());
                // f.delete();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
        return response;
    }

    /**
     * 单个文件下载 <br/>
     * <p>
     * Description: TODO(详细描述) <br/>
     * <p>
     * Author: Administrator<br/>
     * <p>
     * Date: 2013-12-25-下午01:56:59<br/>
     * <p>
     * 
     * @param path
     * @param response
     * @return
     * 
     */
    public static HttpServletResponse downloadFile(String path, HttpServletResponse response)
    {
        OutputStream toClient = null;
        try
        {
            File file = new File(path);
            // 取得文件名。
            String filename = file.getName();
            // 取得文件的后缀名。
            String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();

            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(path));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();

            toClient = new BufferedOutputStream(response.getOutputStream());

            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
            response.setCharacterEncoding("utf-8");
            response.setContentType(CodeUtil.ext2ct(ext));

            // response.setContentType("application/octet-stream");
            // response.setHeader("Content-Disposition", "attachment;filename=" + file.getName());
            toClient.write(buffer);
            toClient.flush();
        }
        catch (IOException ex)
        {
            ex.printStackTrace();
        }
        finally
        {
            try
            {
                toClient.close();
                // File f = new File(file.getPath());
                // f.delete();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
        return response;
    }

}
